<!--
Date: 2025-08-13
Copyright (c) 2025 Industrial Software Feature Database
-->
<template>
  <el-dialog v-model="props.elementVisible" title="零件详情" width="1200" @close="handleVisible">
    <div class="element_view">
      <div class="top">
        <div class="title">零件号：{{ detailData?.partNumber }}</div>
        <div class="basic">
          <div class="item">
            <span>零件名称：</span>
            <span>{{ detailData?.name }}</span>
          </div>
          <div class="item">
            <span>机型：</span>
            <span>{{ detailData?.modelName }}</span>
          </div>
          <div class="item">
            <span>部段：</span>
            <span>{{ detailData?.sectionName }}</span>
          </div>
          <div class="item">
            <span>组件：</span>
            <span>{{ detailData?.componentNumber }}</span>
          </div>
        </div>
      </div>
      <el-divider style="margin: 0; margin-top: 10px" />
      <div class="info">
        <div class="left">
          <div class="title">版本号</div>
          <ul>
            <li v-for="item in version" :class="{ active: item.versionNumber === currentTab }" :key="item.versionNumber" @click="versionClick(item)">
              {{ item.versionNumber }} 版本
            </li>
          </ul>
        </div>
        <div class="right">
          <div class="top">
            <div>版本信息</div>
          </div>
          <el-divider style="margin: 0; margin-top: 10px" />
          <div class="basic">
            <div class="item">
              <span>版本号：</span>
              <span>{{ versionDetail?.versionNumber }}版本</span>
            </div>
            <div class="item">
              <span>单件重量：</span>
              <span>{{ versionDetail?.unitWeight }}<span v-if="versionDetail?.unitWeight">kg</span></span>
            </div>
            <div class="item">
              <span>数量：</span>
              <span>{{ versionDetail?.amount }}</span>
            </div>
            <div class="item">
              <span>材料：</span>
              <span>{{ versionDetail?.material }}</span>
            </div>
          </div>
          <div class="title">模型情况</div>
          <el-divider style="margin: 0; margin-top: 10px" />
          <el-tabs v-model="activeName" class="tabs" @tab-click="handleClick">
            <el-tab-pane label="模型预览" name="preView">
              <Suspense>
                <template #default>
                  <div style="width: 100%; height: 500px" v-loading="loading">
                    <showThree
                      ref="threeRef"
                      :key="showThreeKey"
                      :model-info="modelInfo"
                      :shrink="threeShrink"
                      :showInfo="true"
                      @on-select="selectFn"
                      :selected-elements="selectElementFn"
                      @load-end="loadEnd"
                    />
                  </div>
                </template>
                <template #fallback>
                  <h1>Loading !...</h1>
                </template>
              </Suspense>
              
            </el-tab-pane>
            <el-tab-pane label="BDF文件" name="bdf">
              <div class="bdf" v-loading="loading" style="display: flex;">
                <!-- <div class="bdf_search" v-if="searchVisible">
                  <el-input size="small" v-model.trim="searchContent" style="width: 140px" placeholder="请输入要查询的内容" />
                  <el-button type="primary" size="small" style="margin-left: 10px" @click="searchFn">查询</el-button>
                  <el-button size="small" icon="Top" @click="preFn">上一个</el-button>
                  <el-button size="small" icon="Bottom" @click="nextFn">下一个</el-button>
                  <el-button size="small" icon="Close" @click="closeSearch">关闭</el-button>
                </div> -->
                <div style="width: 100%; max-height: 300px; overflow: auto" id="bdfContent" class="bdf_div">
                  <div class="bdf-item" v-for="(item, index) in dataList" :key="index">
                    <el-tooltip
                      v-if="item.cardType == 'PSHELL'"
                      class="box-item"
                      effect="dark"
                      content="点击可修改单元属性信息"
                      placement="top-start"
                    >
                      <p :class="['pshell-item','bdf-con-'+item.number,  currentSearchIndex == item.number ? 'active' : '']" @click="pshellClick(item)">
                        <span style="display: inline-block; width: 50px;">{{item.number}}</span>
                        <span v-for="(place, i) in items" :key="i" :class="[searchContent && searchContent == item[place.name] && hasSearchContent ? 'search-item-active' : '', !item[place.name] ? 'empty' : 'bg-cover']" v-html="handlePlaceStr(item[place.name])"></span>  
                      </p>
                    </el-tooltip>
                    <p v-else :class="['pshell-item', 'bdf-con-'+item.number, currentSearchIndex == item.number ? 'active' : '']">
                      <span style="display: inline-block; width: 50px;">{{item.number}}</span>
                      <span v-for="(place, i) in items" :key="i" :class="[searchContent && searchContent == item[place.name] && hasSearchContent ? 'search-item-active' : '', !item[place.name] ? 'empty' : 'bg-cover']" v-html="handlePlaceStr(item[place.name])"></span>  
                    </p>
                  </div>
                </div>

                <div class="bdf_search-wrapper">
                  <div class="search-btn">
                    <el-input size="small" v-model.trim="searchContent" style="width: 140px" placeholder="请输入关键词" />
                    <el-button type="primary" size="small" style="margin-left: 10px" @click="searchFn">查询</el-button>
                  </div>
                  <div class="search-con">
                    <el-select size="small" style="width: 120px;" v-model="cardType" clearable placeholder="请选择查询类型">
                      <el-option v-for="item in bdfTypeList" :key="item.card" :label="item.card" :value="item.card"></el-option>
                    </el-select>
                    <!-- <el-input style="width: 80px; margin-left: 10px;" v-model="searchContent" size="small"></el-input> -->
                    <!-- <el-button type="text" size="small" icon="Top" @click="preFn"></el-button> -->
                    <el-text style="margin-left: 20px;" class="mx-1">{{pageIndex}}</el-text>/<el-text style="margin-right: 10px;" class="mx-1">{{ markIndexList.length }}</el-text>
                      <el-icon :disabled="pageIndex <= 1" size="small" color="#000" @click="preFn">
                        <ArrowUp />
                      </el-icon>
                      <el-icon :disabled="pageIndex >= markIndexList.length" size="small" color="#000" @click="nextFn">
                        <ArrowDown />
                      </el-icon>
                      <el-icon size="small" color="#000" @click="delFn">
                        <Close />
                      </el-icon>
                    <!-- <el-button type="text" size="small" icon="Bottom" @click="nextFn"></el-button>
                    <el-button type="text" size="small" icon="Close" @click="closeSearch"></el-button> -->
                  </div>
                  
                  <div class="node-statistics">
                    <el-collapse v-model="activeNames" @change="handleChange">
                      <el-collapse-item title="节点统计信息" name="1" :icon="CaretRight">
                        <div v-if="bdfTypeMap && bdfTypeMap['bdf.nodes']" class="node-statistics-item">
                          <div class="head">
                           <span>bdf.nodes:</span>  
                           <!-- <el-link type="primary">543</el-link> -->
                          </div>
                          <div class="con" v-for="sta in bdfTypeMap['bdf.nodes']" :key="sta.card">
                            <span> - {{ sta.card}}:</span>  <el-link type="primary" @click="linkToCard(sta.card)">{{sta.value}}</el-link>
                          </div>
                        </div>
                        <div v-if="bdfTypeMap && bdfTypeMap['bdf.elements']" class="node-statistics-item">
                          <div class="head">
                           <span>bdf.elements:</span>  
                           <!-- <el-link type="primary">1104</el-link> -->
                          </div>
                          <div class="con" v-for="sta in bdfTypeMap['bdf.elements']" :key="sta.card">
                            <span> - {{ sta.card}}:</span>  <el-link type="primary" @click="linkToCard(sta.card)">{{sta.value}}</el-link>
                          </div>
                        </div>
                        <div v-if="bdfTypeMap && bdfTypeMap['bdf.properties']" class="node-statistics-item">
                          <div class="head">
                           <span>bdf.properties:</span>  
                           <!-- <el-link type="primary">543</el-link> -->
                          </div>
                          <div class="con" v-for="sta in bdfTypeMap['bdf.properties']" :key="sta.card">
                            <span> - {{ sta.card}}:</span>  <el-link type="primary" @click="linkToCard(sta.card)">{{sta.value}}</el-link>
                          </div>
                        </div>
                        <div v-if="bdfTypeMap && bdfTypeMap['bdf.materials']" class="node-statistics-item">
                          <div class="head">
                           <span>bdf.materials:</span>  
                           <!-- <el-link type="primary">543</el-link> -->
                          </div>
                          <div class="con" v-for="sta in bdfTypeMap['bdf.materials']" :key="sta.card">
                            <span> - {{ sta.card}}:</span>  <span>{{sta.value}}</span>
                          </div>
                        </div> 
                      </el-collapse-item>
                    </el-collapse>
                  </div>
                </div>
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
      </div>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button size="small" @click="handleVisible">关闭</el-button>
      </div>
    </template>
    <div id="bdfTmp" style="display: none"></div>
  </el-dialog>
  <PshellEdit v-if="pshellDialogShow" :visible="pshellDialogShow" :pshellItem="pshellItem" :partId="partId" @handleEvent="handlePshellEdit" />
</template>
<script setup name="ElementView">
import ShowThree from '@/components/ShowThree/index.vue';
import PshellEdit from "./PshellEdit.vue";
import { getModelDetailById, queryBdfFileInfo, loadPartRender, getModelManagementCardStruct, searchModelManagementCard } from '@/api/elementsLibrary';
import { mark } from '@/components/SuperFlow/utils';

const props = defineProps(['elementVisible', 'data']);
const emit = defineEmits(['close']);
const showThreeKey = ref(0);
const modelInfo = ref({ url: '', userDataUrl: '' });
const threeShrink = ref(0);
const selectFn = () => {};
const selectElementFn = () => {};
const loadEnd = () => {};
const detailData = ref(null);
const versionDetail = ref(props?.data);
const renderList = ref([]);
const currentTab = ref(props?.data?.versionNumber);
const activeName = ref('preView');
const version = ref([]);
const loading = ref(false);
const searchVisible = ref(false);
const searchContent = ref();
const pshellDialogShow = ref(false);
//当前文本搜索的所有内容
const elements = ref([]);
// 搜索相关
const currentSearchIndex = ref(-1);
const pageIndex = ref(1);
const searchKey = ref('all');
const activeNames = ref(['1']);
const hasSearchContent = ref(false);
const items = ref([
  {
    id: 1, 
    name: 'place1',
  },
  { 
    id: 2,                     
    name: 'place2',           
  },          
  {                     
    id: 3,                                
    name: 'place3',                                             
  },                                                                 
  {                                                                     
    id: 4,                                                                               
    name: 'place4',                                                                                    
  },                                                                                                                
  {                                                                                                                          
    id: 5,                                                                                                                                    
    name: 'place5',                                                                                                                                     
  },     
  {                                                                                                                          
    id: 6,                                                                                                                                    
    name: 'place6',                                                                                                                                     
  },
  {                                                                                                                          
    id: 7,                                                                                                                                    
    name: 'place7',                                                                                                                                     
  },
  {                                                                                                                          
    id: 8,                                                                                                                                    
    name: 'place8',                                                                                                                                     
  },
  {                                                                                                                          
    id: 9,                                                                                                                                    
    name: 'place9',                                                                                                                                     
  },
  {                                                                                                                          
    id: 10,                                                                                                                                    
    name: 'place10',                                                                                                                                     
  },                                                                                                                                                                                                                                                                                                                   
]);
const partId = ref('');
const cardType = ref('');
const bdfTypeMap = ref({});
const bdfTypeList = ref([]);
const dataList = ref([]);
const pshellItem = ref(null);
const handleVisible = () => {
  emit('close');
};
const markIndexList = ref([]) // 搜索匹配得行号
const handleClick = (e) => {
  activeName.value = e;
  if (e.props.name === 'bdf') {
    let data = version.value.find(item => item.versionNumber === currentTab.value);
    updateBdfInfo(data);
  }
};
// 更新bdf文件信息
const updateBdfInfo = (data) => {
  loading.value = true;
  dataList.value = [];
  getModelManagementCardStruct({
    "classification":"model_management_part_data_prefix",
    "uri": data?.indexPath,
    "modelNumber": props.data?.modelNumber,
    "sectionNumber": props.data?.sectionNumber,
    // "partNumber": data?.partNumber,
    // "versionNumber":currentTab.value,
    "partId": data?.id
  })
  .then(res => {
    partId.value = res.data.partId;
    bdfTypeMap.value = res.data.statsMap;
    dataList.value = res.data.cardList;
    bdfTypeList.value = [];
    for(let key in res.data.statsMap) {
      if (res.data.statsMap[key] && res.data.statsMap[key].length > 0) {
        bdfTypeList.value = [...bdfTypeList.value, ...res.data.statsMap[key]]
      }
    }
  })
  .finally(() => {
    loading.value = false;
  });
}

// 节点统计信息跳转对应行
const linkToCard = (card) => {
  searchContent.value = ''; 
  searchModelManagementCard({
    "partId": partId.value,
    "cardType":card,
    "place": ''
  }).then(res => {
    hasSearchContent.value = true;
    markIndexList.value = res.data.matchNumberList;
    currentSearchIndex.value = markIndexList.value[0]; // 重置搜索位置
    pageIndex.value = 1; // 重置页数
    const row = document.getElementsByClassName(`bdf-con-${currentSearchIndex.value}`)[0];
    row.scrollIntoView({ behavior: 'smooth' });
  })
}
// 设置CQUAD4单元颜色
const setItemColor = (CQUAD4) => {
  if (!CQUAD4) {
    return;
  }
  let data = CQUAD4.split('  ');
  const colorArr = data.slice(1, data.length);
  const colorStr = colorArr.join('  ');
  const step = 8;
  const num = colorStr.length / step;
  let str = '';
  for (let i = 0; i < num; i++) {
    const color1 = '#d7d7d7';
    const color2 = '#f2f2f2';
    let color = '';
    let strItem = colorStr.slice(i * 8, (i + 1) * 8);
    //交替设置颜色
    if (i % 2 === 0) {
      color = color1;
    } else {
      color = color2;
    }
    str += `<span style="white-space:pre;width:54px;display: inline-block;background: ${color};">${strItem}</span>`;
  }
  const showStr = `<div style="white-space:pre;">${data[0]}&nbsp;&nbsp;${str}</div>`;
  return showStr;
};
const versionClick = (data) => {
  currentTab.value = data.versionNumber;
  versionDetail.value = data;
  if (activeName.value === 'bdf') {
    updateBdfInfo(data);
    delFn();
  }
};
const closeSearch = () => {
  searchVisible.value = false;
};
// place字符串空格处理
const handlePlaceStr = (str) => {
  let len = str.length;
  let emptyHtml = '';
  if (8 - len > 0) {
    for(let i = 0; i < 8 - len; i++) {
      emptyHtml += '<span style="width:6.675px;display: inline-block;"></span>';
    }
  }
  // emptyHtml += '</span>';
  return str + emptyHtml;
}
// pshell点击事件
const pshellClick = (item) => {
  let data = version.value.find(item => item.versionNumber === currentTab.value);
  pshellItem.value = {
    ...item,
    versionNumber: data.versionNumber,
    remarks: data.remarks,
  };
  pshellDialogShow.value = true;
}
const searchFn = () => {
  if (!searchContent.value || searchContent.value.length !== 8) {
    // findText();
    ElMessage({ showClose: true, message: '请输入8位字符串进行搜索', type: 'waring' });
    return;
  }
  searchModelManagementCard({
    "partId": partId.value,
    "cardType":cardType.value,
    "place": searchContent.value
  }).then(res => {
    hasSearchContent.value = true;
    markIndexList.value = res.data.matchNumberList;
    currentSearchIndex.value = markIndexList.value[0]; // 重置搜索位置
    pageIndex.value = 1; // 重置页数
    const row = document.getElementsByClassName(`bdf-con-${currentSearchIndex.value}`)[0];
    row.scrollIntoView({ behavior: 'smooth' });
  }).catch(e => {
    currentSearchIndex.value = -1;
    hasSearchContent.value = false;
    markIndexList.value.length = 0;
    pageIndex.value = 1;
    const row = document.getElementsByClassName(`bdf-con-1`)[0];
    row.scrollIntoView({ behavior: 'smooth' });
  })
};
  
// 下一个
const nextFn = () => {
  if (!hasSearchContent.value) return;
  if (pageIndex.value === markIndexList.value.length) {
    ElMessage({ showClose: true, message: '已是匹配的最后一条数据', type: 'waring' });
    return;
  }
  pageIndex.value ++;
  currentSearchIndex.value = markIndexList.value[pageIndex.value - 1];
  const row = document.getElementsByClassName(`bdf-con-${currentSearchIndex.value}`)[0];
  row.scrollIntoView({ behavior: 'smooth' });
};
// 上一个
const preFn = () => {
  if (!hasSearchContent.value) return;
  if (pageIndex.value === 1) {
    ElMessage({ showClose: true, message: '已是匹配的第一条数据', type: 'waring' });
    return;
  }
  pageIndex.value --;
  currentSearchIndex.value = markIndexList.value[pageIndex.value - 1];
  const row = document.getElementsByClassName(`bdf-con-${currentSearchIndex.value}`)[0];
  row.scrollIntoView({ behavior: 'smooth' });
};
const delFn = () => {
  cardType.value = '';
  currentSearchIndex.value = -1;
  markIndexList.value.length = 0;
  searchContent.value = '';
  pageIndex.value = 1;
  const row = document.getElementsByClassName(`bdf-con-1`)[0];
  row.scrollIntoView({ behavior: 'smooth' });
}


// 处理Pshell编辑事件
const handlePshellEdit = async (data) => {
  pshellDialogShow.value = false;
  if (data.type === 'refresh') {
    // 生版后重新渲染零件详情页
    await queryModelDetail();
    if (activeName.value === 'bdf') {
      currentTab.value = version.value[version.value.length - 1].versionNumber;
      let data = version.value.find(item => item.versionNumber === currentTab.value);
      updateBdfInfo(data);
      delFn();
    }
  }
};
// 查找
const findText = async () => {
  const bdfDomHtml = document.getElementById('bdfContent').innerHTML;
  //先置空之前设置的样式
  const resetHtml1 = bdfDomHtml.replaceAll(`<span class="search_span" style="background:#bbd6fb;">`, ``);
  const resetHtml2 = resetHtml1.replaceAll(`</span>`, ``);
  const repalceStr = resetHtml2.replaceAll(searchContent.value, `<span class="search_span" style="background:#bbd6fb;">${searchContent.value}</span>`);
  document.getElementById('bdfContent').innerHTML = repalceStr;
  // 查找所有匹配selector的元素
  elements.value = document.querySelectorAll(`.search_span`) || [];
  if (elements.value.length === 0) {
    ElMessage({ showClose: true, message: '未检索到相关查询内容', type: 'waring' });
    return;
  }
  scrollToContent(0);
};
const scrollToContent = (index) => {
  // 默认滚动至第一条数据位置
  if (elements.value.length > 0) {
    if (elements.value[index]) {
      elements.value[index].scrollIntoView({ behavior: 'smooth' });
    }
  } else {
    ElMessage({ showClose: true, message: '未检索到相关查询内容', type: 'waring' });
  }
};
// 查询零件详情
const queryModelDetail = async () => {
  await getModelDetailById({ partNumber: props.data?.partNumber,modelNumber:props.data?.modelNumber,batchNumber:props.data?.batchNumber,sectionNumber:props.data?.sectionNumber,componentNumber:props.data?.componentNumber }).then((res) => {
    if (res) {
      detailData.value = res?.data;
      // 设置版本列表
      version.value = res?.data?.versionVoList || [];
    }
  });
};
// 查询模型预览
const loadRender = () => {
  loading.value = true;
  loadPartRender({ businessId: versionDetail.value.id, type: 'part' })
    .then(async (res) => {
      renderList.value = res.data;
      modelInfo.value.url = `/file${res?.data?.gltfPath}`;
      modelInfo.value.userDataUrl = `/file${res?.data?.xrefPath}`;
    })
    .finally(() => {
      loading.value = false;
    });
};
onMounted(async () => {
  await queryModelDetail();
  loadRender();
  window.addEventListener('keydown', function (e) {
    if (e.ctrlKey && e.key === 'f' && activeName.value === 'bdf') {
      e.preventDefault();
      searchVisible.value = true;
    }
  });
});
onUnmounted(() => {
  window.removeEventListener('keydown', function () {});
});
</script>
<style lang="scss" scoped>
.element_view {
  li {
    list-style: none;
    padding: 5px;
    cursor: pointer;
    width: 80px;
    text-align: center;
    font-size: 12px;
  }
  li:hover {
    background: #d9d9dd;
  }
  ul {
    margin: 0;
    padding: 0;
  }
  .top {
    .title {
      font-weight: 600;
    }
    .basic {
      display: flex;
      flex-wrap: wrap;
      .item {
        width: 300px;
        margin: 5px 0;
        font-size: 12px;
        > span:nth-child(2) {
          color: #909399;
        }
      }
    }
  }
  .info {
    height: 100%;
    display: flex;
    .left {
      width: 80px;
      padding-top: 10px;
      border-right: 1px solid #dcdfe6;
      .active {
        color: #409eff;
      }
    }
    .title {
      font-size: 12px;
    }
    .right {
      width: calc(100% - 80px);
      padding: 10px;
      .tabs {
        font-size: 12px;
      }
      .title {
        font-size: 12px;
        font-weight: 600;
        margin-top: 12px;
      }
      .top {
        display: flex;
        justify-content: space-between;
        > div {
          font-weight: 600;
          font-size: 12px;
        }
      }
      .basic {
        display: flex;
        flex-wrap: wrap;
        .item {
          width: 250px;
          margin: 5px 0;
          font-size: 12px;
          > span:nth-child(2) {
            color: #909399;
          }
        }
      }
    }
  }
  :deep(.el-tabs__item) {
    font-size: 12px;
  }
  .bdf {
    position: relative;
    width: 100%;
    max-height: 300px;
    display: flex;
    flex-direction: row;
    // align-items: end;
    .bdf_div {
      flex: 1;
      .bdf-item {
        .pshell-item {
          cursor: pointer;
          span:nth-child(odd) {
            &.bg-cover {
              background: rgba(0, 0, 0, 0.1);
            }
            &.search-item-active {
              background: pink;
           }
          }
        }
      }
      .active {
        color: blue;
      }
      .search-item-active {
        background: pink;
      }
    }
    .bdf_search-wrapper {
      flex: 0 0 300px;
      .search-btn {
        padding: 0 5px;
      }
      .search-con {
        display: flex;
        align-items: center;
        // margin-top: 10px;
        padding: 5px;
        .el-icon {
          font-size: 16px;
          margin-left: 5px;
        }
      }
      .node-statistics {
        max-height: 240px;
        overflow-y: scroll;
        padding: 5px;
      }
    }
    .bdf_search {
      // width: 500px;
      position: sticky;
      top: 0;
      display: flex;

      border: 1px solid #e8e8e8;
      padding: 5px 10px;
      // border-radius: 10px;
      background: #fff;
    }
  }
}
</style>